home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-20 | 30.6 KB | 984 lines | [TEXT/MMCC] |
-
- /*
- File: MovieStuff.c
- Contains: movie handling routines
- Written by: Jason Hodges-Harris & Don Swatman
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
- */
-
- //==============================================
- // MovieStuff.c
- //
- // This handles all the clever movie stuff.
- // - Sets up movie windows
- // - Tears down movie windows
- // - handles updates and events
- // - handles slaving, altering playback speed, looping etc
- //==============================================
-
- #include <Memory.h>
- #include <TextUtils.h>
- #include <Movies.h>
-
- #include "MovieStuff.h"
- #include "WindStuff.h"
-
- //==============================================
- // CallBackInfoType
- //
- // This structure is used to store QuickTime
- // call backs and any data they require.
- // - It has a several parameters at the front,
- // then a variable size record at the end. It also
- // needs the parameters used in CallMeWhen
- // - It's size is:
- // "sizeof(CallBackInfoType) + callBackDataSize - sizeof(long)"
- // - Data should not contain the only reference
- // to other handles, as it can't dispose of them
- // - It forms a linked list. Any new items are
- // added to the front.
- // - It should be passed in the call backs
- // reference field.
- //==============================================
-
- struct CallBackInfoType
- {
- struct CallBackInfoType **hNextCallBackInfo; // Next in the list
-
- QTCallBack actualCallBack; // the call back
- WindowPtr pParentWindow; // parent window of the movie
- long param1; // Used in "CallMeWhen"
- long param2; // Used in "CallMeWhen"
- long param3; // Used in "CallMeWhen"
- long callBackDataSize; // Size of the data attached on the end
- long callBackDataStart; // where the data starts
- };
-
- typedef struct CallBackInfoType CallBackInfoType,
- *CallBackInfoPtr, **CallBackInfoHdl;
-
- //==============================================
- // DocMovieInfoType
- //
- // Used to hold information about a movie within
- // a window
- // - It should be attached to the windows RefCon
- //==============================================
-
- struct DocMovieInfoType
- {
- FSSpec movieFileSpec; // movies File Spec
- MovieController movieControls; // standard movie controller
- Movie actualMovie; // the Movie itself!
- Boolean movieAutoClose; // True if the window closes after movie finishes
- TimeBase moviesTimeBase;
- TimeScale moviesTimeScale;
- CallBackInfoHdl hFirstCallBackData; // Handle to first item of the call back info list
- WindowPtr pSlaveWind; // WindowPtr of this movies slave
- };
-
- typedef struct DocMovieInfoType DocMovieInfoType,
- *DocMovieInfoPtr, **DocMovieInfoHndl;
-
- //==============================================
- // Global Stuff, init and tear down
- //==============================================
-
- // Prototypes of functions used in UPPs
- pascal void StartMovieCB(QTCallBack myCallBack,long ref);
- pascal void AlterRate( QTCallBack myCallBack,long ref);
- pascal void AlterMasterOffset( QTCallBack myCallBack,long ref);
-
- // Global UPPs
- QTCallBackUPP gStartMovieCBUpp;
- QTCallBackUPP gAlterRateUpp;
- QTCallBackUPP gAlterMasterOffsetUpp;
-
- //----------------------------------------------
- // InitMovieGlobals
- //
- // Init's any globals used in MovieStuff
- // i.e. the UPPs
- //----------------------------------------------
- void InitMovieGlobals(void)
- {
- gStartMovieCBUpp = nil;
- gAlterRateUpp = nil;
- gAlterMasterOffsetUpp = nil;
-
- // Create routine descriptor for "StartMovieCB" QT callback routine
- gStartMovieCBUpp = NewQTCallBackProc(StartMovieCB);
-
- // Create routine descriptor for "AlterRate" QT callback routine
- gAlterRateUpp = NewQTCallBackProc(AlterRate);
-
- // Create routine descriptor for "AlterMasterOffset" QT callback routine
- gAlterMasterOffsetUpp = NewQTCallBackProc(AlterMasterOffset);
-
- }
-
- //----------------------------------------------
- // KillMovieGlobals
- //
- // Removes the UPPs
- //----------------------------------------------
- void KillMovieGlobals(void)
- {
- // Clear the Universal Proc Pointers
- // You don't need to do this as quiting the app will do it for you,
- // however, I have this thing about neatness.
- if (gStartMovieCBUpp)
- DisposeRoutineDescriptor(gStartMovieCBUpp);
- if (gAlterRateUpp)
- DisposeRoutineDescriptor(gAlterRateUpp);
- if (gAlterMasterOffsetUpp)
- DisposeRoutineDescriptor(gAlterMasterOffsetUpp);
-
- }
-
-
- //==============================================
- //
- // Error Reporting
- //
- //==============================================
-
- //----------------------------------------------
- // Report Error
- //
- // If an error occurs, Uses DebugStr to send out
- // some text passed to it, then the error number
- //----------------------------------------------
-
- void ReportError( Str255 errText, OSErr theErr );
- void ReportError( Str255 errText, OSErr theErr )
- {
- Str255 errorStr;
-
- // Check there is an error
- if (theErr)
- {
- // convert theErr number to text
- NumToString(theErr,errorStr);
-
- // if there is error text then displat it
- if (errText != "\p")
- DebugStr(errText);
- // Display error number
- DebugStr(errorStr);
- }
- }
-
- //----------------------------------------------
- // GetAndReportError
- //
- // Checks GetMoviesError and reports error if
- // needed
- //----------------------------------------------
- OSErr GetAndReportError( Str255 errText );
- OSErr GetAndReportError( Str255 errText )
- {
- OSErr theErr;
-
- theErr = GetMoviesError(); // Get Movies error number
- ReportError( errText, theErr ); // And report it
- return(theErr); // Oh yeh, return it to the caller
- }
-
- //==============================================
- //
- // Call Back info stuff
- //
- // Following routines handle the CallBackInfoHdl
- // structure.
- //==============================================
-
- //----------------------------------------------
- // AddNewCallBackInfo
- //
- // Creates a new "CallBackInfoHdl", intialises and
- // returns it
- // - It puts "pWindow" and "theCallBack" into the structure
- // - It appends "dataSize" bytes of data from "pDataStart"
- // on to the end of the structure
- //----------------------------------------------
-
- CallBackInfoHdl AddNewCallBackInfo( WindowPtr pWindow,
- QTCallBack theCallBack,
- Ptr pDataStart,
- long dataSize,
- long param1,
- long param2,
- long param3
- );
- CallBackInfoHdl AddNewCallBackInfo( WindowPtr pWindow,
- QTCallBack theCallBack,
- Ptr pDataStart,
- long dataSize,
- long param1,
- long param2,
- long param3
- )
- {
- CallBackInfoHdl hNewCBInfo = nil; // the new call back info record
- DocMovieInfoHndl hDocMovieInfo;
- long newSize; // Size of hNewCBInfo and the data added to it
-
- // Calculate how big the block needs to be
- newSize = sizeof(CallBackInfoType) + dataSize - sizeof(long);
-
- // Create the call back data item
- hNewCBInfo = (CallBackInfoHdl) NewHandle (newSize);
-
- // Check that we actualy did create it!
- if (hNewCBInfo)
- {
-
- // Setup the structure
-
- (**hNewCBInfo).hNextCallBackInfo = nil;
- (**hNewCBInfo).actualCallBack = theCallBack;
- (**hNewCBInfo).pParentWindow = pWindow;
- (**hNewCBInfo).param1 = param1;
- (**hNewCBInfo).param2 = param2;
- (**hNewCBInfo).param3 = param3;
- (**hNewCBInfo).callBackDataSize = 0;
-
- // Add in the data (if there is any)
-
- if (dataSize && pDataStart)
- {
- (**hNewCBInfo).callBackDataSize = dataSize;
- BlockMove( pDataStart, &((**hNewCBInfo).callBackDataStart), dataSize);
- }
-
- // Now, link it into the window data structure (attach it to the front of the chain)
-
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon ( pWindow );
- (**hNewCBInfo).hNextCallBackInfo = (**hDocMovieInfo).hFirstCallBackData;
- (**hDocMovieInfo).hFirstCallBackData = hNewCBInfo;
- }
-
- return( hNewCBInfo );
- }
-
- //----------------------------------------------
- // RemoveCallBackInfo
- //
- // Scans down the CallBackInfoHdl chain and disposes
- // of each one
- //----------------------------------------------
-
- void RemoveCallBackInfo ( CallBackInfoHdl hFirstItem );
- void RemoveCallBackInfo ( CallBackInfoHdl hFirstItem )
- {
- CallBackInfoHdl hNextCBInfo;
- CallBackInfoHdl hDisposeData;
-
- if (hFirstItem)
- {
- // Scan down the chain of items, disposing as we go
- hNextCBInfo = hFirstItem;
- while (hNextCBInfo)
- {
- hDisposeData = hNextCBInfo;
- hNextCBInfo = (**hNextCBInfo).hNextCallBackInfo;
-
- // Dispose of the call back
- DisposeCallBack( (**hDisposeData).actualCallBack );
-
- // Dispose of the call back info block
- DisposeHandle( (Handle) hDisposeData);
- }
- }
-
- }
-
- //----------------------------------------------
- // GetDataFromCBInfo
- //
- // Extracts the data from a CallBackInfoHdl and
- // moves the data into it. Checks the stored structure
- // is smaller than requested size. Ideally they should
- // be the same size.
- //----------------------------------------------
-
- Boolean GetDataFromCBInfo ( CallBackInfoHdl hCallBackInfo,
- Ptr pData,
- long maxDataSize );
- Boolean GetDataFromCBInfo ( CallBackInfoHdl hCallBackInfo,
- Ptr pData,
- long maxDataSize )
- {
- Boolean isOk = false;
-
- // Check that we have a call back,
- // and we have some where to put the data,
- // and it's bigger than 0
- if (hCallBackInfo && pData && maxDataSize)
-
- // Check the call back data is smaller than the new structure
- if ( (**hCallBackInfo).callBackDataSize <= maxDataSize)
- {
-
- // Move the data to pData
- BlockMove ( &((**hCallBackInfo).callBackDataStart),
- pData,
- (**hCallBackInfo).callBackDataSize );
- isOk = true;
- }
- return ( isOk );
- }
-
- //----------------------------------------------
- // IsMoviePlaying
- //
- // Find out if any movie is playing
- //----------------------------------------------
-
- Boolean IsMoviePlaying (void)
- {
- DocMovieInfoHndl hDocMovieInfo; // The movie we're checkings info
- Boolean movieLive = false; // set to true if there is a live window
- short windCount;
-
- // Scan the window list until we've found a live window
- for (windCount = 0;(windCount < kMaxWindows) && !movieLive; windCount++ )
- // If this window is open
- if (gTheWinds[windCount])
- {
- // Get information about the movie
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon (gTheWinds[windCount]);
-
- // Use IsMovieDone to see if it's still running
- if (!IsMovieDone((**hDocMovieInfo).actualMovie) )
- movieLive = true;
- }
- return (movieLive);
- }
-
- //----------------------------------------------
- // UpdateMovieWindow
- //----------------------------------------------
- void UpdateMovieWindow ( WindowPtr pWindow )
- {
- // Get the movie from the ref con and update it. Easy.
- UpdateMovie( (**(DocMovieInfoHndl)GetWRefCon( pWindow )).actualMovie);
- }
-
- //----------------------------------------------
- // Load a movie into memory
- //
- // Use standard file to get and load a movie
- //----------------------------------------------
- void LoadOneMovie( DocMovieInfoHndl hDocMovieInfo );
- void LoadOneMovie( DocMovieInfoHndl hDocMovieInfo )
- {
- Movie myNewMovie = nil; // The new movie
- StandardFileReply newMovieFile; // Standard File Reply about the movies file
- Str255 myMovieName; // The Movies name
- OSErr error;
- SFTypeList myTypes = {MovieFileType}; // File types we want Standard File to get
- short myMovieResFile; // Movie files ref number
- short myMovieResID = 0; // Load the first movie res
- Boolean movieChanged; // Set to true if movie was changed durring
- // loading to resolve references
-
- // Use standard file to get the fsSpec etc.
- StandardGetFilePreview(nil,1,myTypes,&newMovieFile);
- if (newMovieFile.sfGood)
- {
- // Open the movie file
- error = OpenMovieFile( &newMovieFile.sfFile, &myMovieResFile, fsRdPerm);
- if (error==noErr)
- {
- // Store the file spec
- (**hDocMovieInfo).movieFileSpec = newMovieFile.sfFile;
-
- // Move Movie data in to memory
- error = NewMovieFromFile( &myNewMovie, myMovieResFile, &myMovieResID,
- myMovieName, newMovieActive, &movieChanged);
-
- // Close the file as we succeded in opening it
- CloseMovieFile (myMovieResFile);
- }
- }
- (**hDocMovieInfo).actualMovie = myNewMovie; // Return myNewMovie
- }
-
- //----------------------------------------------
- // ServiceMovieTasks
- //
- // Used to Handle the null event. You need to handle
- // this to make the movie play!
- // - First it sees if the movie controller has an event
- // - Scans the window list looking for movies
- // - If the movie has finished then close it if the
- // flags are set that way
- // - If any movies are active, then call MoviesTask
- // to make them play
- // - Finally return true if the event was handled by the
- // movie controller
- //----------------------------------------------
- Boolean ServiceMovieTasks ( WindowPtr pWindow, const EventRecord *theEvent )
- {
- #pragma unused ( pWindow )
-
- Boolean doneProccessing = false; // goes to true if MCIsPlayerEvent handles event
- DocMovieInfoHndl hDocMovieInfo; // Current windows movie info
- short windCount;
- Boolean needMovieTasks = false; // Goes true if there is a movie running
- Boolean moviePlaying;
-
- // Scan window list
- for (windCount = 0;windCount < kMaxWindows; windCount++ )
- if (gTheWinds[windCount])
- {
- // Get movie information for this window
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon (gTheWinds[windCount]);
-
- // Handle any events to this windows movie controller if it's got one
- if (!doneProccessing)
- if ((**hDocMovieInfo).movieControls)
- if (MCIsPlayerEvent((**hDocMovieInfo).movieControls, theEvent))
- doneProccessing = true;
-
- // Next bit checks to see if a window has finished playing (by using
- // IsMovieDone) and closes it if auto close has been set for it
- moviePlaying = !IsMovieDone((**hDocMovieInfo).actualMovie);
- if ( (**hDocMovieInfo).movieAutoClose && (!moviePlaying) )
- CloseOurWindow( windCount );
- else
- if (moviePlaying)
- needMovieTasks = true; // Hey there's a movie running
- }
-
- // If we have an active movie, then service all movies
- if (needMovieTasks)
- MoviesTask(nil,0);
-
- return ( doneProccessing );
- }
-
- //----------------------------------------------
- // CloseMovieWindow
- //
- // Close a movie window and destroys associated
- // structures. If this is a Master window,
- // sets "*pSlaveWindow" to the slave WindowPtr
- //----------------------------------------------
- OSErr CloseMovieWindow( WindowPtr pWindow,
- WindowPtr *pSlaveWindow )
- {
- DocMovieInfoHndl hDocMovieInfo;
-
- *pSlaveWindow = nil;
-
- // Get movie structure
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon(pWindow);
-
- if (hDocMovieInfo)
- {
- // Set the slave WindowPtr
- *pSlaveWindow = (**hDocMovieInfo).pSlaveWind;
-
- // dispose movie
- DisposeMovie((**hDocMovieInfo).actualMovie);
-
- // dispose of the controller if it exists
- if ((**hDocMovieInfo).movieControls)
- DisposeMovieController ( (**hDocMovieInfo).movieControls );
-
- // dispose of call back structures
- RemoveCallBackInfo ( (**hDocMovieInfo).hFirstCallBackData );
-
- // dispose movie structure
- DisposeHandle( (Handle)hDocMovieInfo );
- }
- return ( noErr );
- }
-
- //----------------------------------------------
- // OpenMovieWindow
- //
- // - Opens a movie
- // - Creates and initialises the windows movie
- // structure "DocMovieInfoHndl"
- // - Creates (if wanted) a movie controller
- // - Sizes the window to fit the movie and controller
- // - Shows the window
- //----------------------------------------------
- OSErr OpenMovieWindow ( WindowPtr pWindow,
- Boolean doesAutoClose,
- Boolean hasControler )
- {
- OSErr theErr = noErr;
- DocMovieInfoHndl hDocMovieInfo = nil; // new window movie information
- Rect moviesRect; // Size of the movie
- Rect newWindRect; // New Windows rect (movie + Controllers rect)
-
- if (!pWindow)
- { // Error !!!!
- DebugStr("\pHey, this window doesn't exists!!");
- theErr = userCanceledErr; // Should be something more appropriate
- }
- else
- {
-
- // allocate new movie doc structure
- hDocMovieInfo = (DocMovieInfoType**) NewHandle (sizeof(DocMovieInfoType));
- if (hDocMovieInfo == nil)
- { // Error !!!!
- DebugStr("\pError allocating doc handle");
- theErr = userCanceledErr; // Should be something more appropriate
- }
- else
- {
- // Set up the hDocMovieInfo record
- (**hDocMovieInfo).movieAutoClose = doesAutoClose;
- (**hDocMovieInfo).hFirstCallBackData = nil;
- (**hDocMovieInfo).movieControls = nil;
- (**hDocMovieInfo).actualMovie = nil;
- (**hDocMovieInfo).pSlaveWind = nil;
-
- // set window refcon to movie doc handle
- SetWRefCon( pWindow, (long)hDocMovieInfo );
- SetPort(pWindow);
-
- // load movie refs into doc structure
- LoadOneMovie ( hDocMovieInfo );
- if ((**hDocMovieInfo).actualMovie == nil)
- { // Cancel button pressed or Error !!!!
- theErr = userCanceledErr; // Should be something more appropriate
- return(theErr);
- }
- else
- {
- // get timebase from movie
- (**hDocMovieInfo).moviesTimeBase = GetMovieTimeBase((**hDocMovieInfo).actualMovie);
- theErr = GetAndReportError( "\pError!! GetMovieTimeBase");
-
- // get timescale from movie
- if (!theErr)
- {
- (**hDocMovieInfo).moviesTimeScale = GetMovieTimeScale((**hDocMovieInfo).actualMovie);
- theErr = GetAndReportError( "\pError!! Getting movie time scale");
- }
-
- if (!theErr)
- if (!hasControler)
- {
- // Don't want a controller, so just
- // Get movies rect as this is the size of the window
- GetMovieBox((**hDocMovieInfo).actualMovie, &newWindRect);
- }
- else
- {
- // We want a movie controller so create it beneath the movie
- // Get the movies rect as this is the size we want to put it in
- GetMovieBox((**hDocMovieInfo).actualMovie, &moviesRect);
-
- //Create a controller and put below the movie. as moviesRect is the size of the movie,
- // the controller will fall outside the rect
- (**hDocMovieInfo).movieControls = NewMovieController ( (**hDocMovieInfo).actualMovie,
- &moviesRect,
- mcTopLeftMovie);
- if ((**hDocMovieInfo).movieControls == nil)
- { // Failed to create controller Error !!!!
- theErr = userCanceledErr; // Should be something more appropriate
- return(theErr);
- }
- else
- {
- // Get movieControllers rect. Because it is attached the movie, it will return
- // the controller and movies size
- theErr = MCGetControllerBoundsRect((**hDocMovieInfo).movieControls, &newWindRect);
- }
- }
-
- if (!theErr)
- {
- // Size the window to fit the movie and controller
- SizeWindow( pWindow,newWindRect.right, newWindRect.bottom,true);
- }
- }
- }
- }
-
- return ( theErr );
- }
-
- //==============================================
- // The time base call back procs
- //==============================================
-
- //----------------------------------------------
- // AlterMasterOffset
- //
- // QuickTime callback used to set the SetTimeBaseValue.
- // - Can be used to make the movie loop.
- // - Takes a value in seconds in the data of
- // the CallBackInfoHdl passed in "ref"
- //----------------------------------------------
-
- pascal void AlterMasterOffset(QTCallBack myCallBack,long ref)
- {
- DocMovieInfoHndl hDocMovieInfo;
- WindowPtr pWindow;
- TimeValue newTimeValue; // Where we want to move to
- OSErr theErr;
-
- // Extract where we want to move to from (CallBackInfoHdl)ref
- if (GetDataFromCBInfo( ( CallBackInfoHdl)ref,
- (Ptr) &newTimeValue, sizeof ( TimeValue ) ))
- {
- pWindow = (**(CallBackInfoHdl)ref).pParentWindow; // Get the parent window
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon ( pWindow ); // Get the movie info
- // Move our position in the movie
- SetTimeBaseValue ( (**hDocMovieInfo).moviesTimeBase,
- newTimeValue,
- (**hDocMovieInfo).moviesTimeScale);
- // Finally must reschedule the call back so that it happens again
- theErr = CallMeWhen ( myCallBack,
- gAlterMasterOffsetUpp, ref,
- (**(CallBackInfoHdl)ref).param1,
- (**(CallBackInfoHdl)ref).param2,
- (**(CallBackInfoHdl)ref).param3);
- }
- }
-
- //----------------------------------------------
- // AlterRate
- //
- // QuickTime callback used to set the movies rate.
- // - Alters the speed of playback.
- // - Takes a value in the data of the CallBackInfoHdl
- // passed in "ref"
- //----------------------------------------------
-
- pascal void AlterRate( QTCallBack myCallBack,long ref)
- {
- #pragma unused ( myCallBack )
-
- DocMovieInfoHndl hDocMovieInfo;
- WindowPtr pWindow;
- long newMovieRate;
-
- // Extract the new speed we want the movie to run at
- if (GetDataFromCBInfo ( ( CallBackInfoHdl)ref, (Ptr) &newMovieRate, sizeof ( long ) ))
- {
- pWindow = (**(CallBackInfoHdl)ref).pParentWindow; // Get the parent window
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon ( pWindow ); // Get the movie info
-
-
- // Change the movies rate
- SetMovieRate((**hDocMovieInfo).actualMovie, newMovieRate);
- }
-
- return;
- }
-
- //----------------------------------------------
- // StartMovieCB
- //
- // QuickTime callback used to start a movie.
- // - Takes a value (Movie) in the data of the CallBackInfoHdl
- // passed in "ref" which is the movie you want to start.
- //----------------------------------------------
-
-
- pascal void StartMovieCB(QTCallBack myCallBack,long ref)
- {
- #pragma unused ( myCallBack )
-
- Movie movieToStart;
-
- if (GetDataFromCBInfo ( ( CallBackInfoHdl)ref, (Ptr) &movieToStart, sizeof ( Movie ) ))
- {
- SetMovieRate(movieToStart,65536);
- }
- }
-
- //==============================================
- // Set up the various options
- //==============================================
-
- //----------------------------------------------
- // SetupMovieRate
- //
- // - Sets up the call backs to change the play back speed
- // of the movie.
- // - "delayBeforeChange" gives the time in seconds when
- // the first speed change happens or a constant that
- // tells it to change at 1/3 (& 2/3) of the movies
- // duration.
- //----------------------------------------------
-
- OSErr SetupMovieRate( WindowPtr pWindow, short delayBeforeChange )
- {
- OSErr theErr = noErr;
- QTCallBack theNewCallBack; // Call Back
- long theCallBackOffset; // When we want to change the rate
- TimeValue theMovieLen; // Length of the movie
- DocMovieInfoHndl hDocMovieInfo; // Info about the windows movie
- CallBackInfoHdl hTempCallBackInfo; // Call back information
- long newMovieRate; // What the new rate will be
-
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon (pWindow);
- if (hDocMovieInfo != nil)
- {
- // Set up the time base value
- SetTimeBaseValue( (**hDocMovieInfo).moviesTimeBase,
- 0,
- (**hDocMovieInfo).moviesTimeScale);
-
-
- // If we're changing by a thirds, we need the movie's length
- if (delayBeforeChange == kOneThird)
- theMovieLen = GetMovieDuration((**hDocMovieInfo).actualMovie);
-
- // ---- First call back - slow playback rate to x2 normal -----
-
- // Work out length of delay before callbacks start
- if (delayBeforeChange == kOneThird)
- theCallBackOffset = theMovieLen*0.3333;
- else
- theCallBackOffset = delayBeforeChange * (**hDocMovieInfo).moviesTimeScale;
-
- // Create a new call back
- theNewCallBack = NewCallBack((**hDocMovieInfo).moviesTimeBase,callBackAtTime);
-
- newMovieRate = 131072; // speed up rate to x2 normal
-
- // Put the call back into call back chain ( and append newMovieRate )
- hTempCallBackInfo = AddNewCallBackInfo( pWindow,
- theNewCallBack,
- (Ptr)&newMovieRate, sizeof ( long ),
- triggerTimeFwd,
- theCallBackOffset,
- (**hDocMovieInfo).moviesTimeScale );
-
- // Attach the call back to the movie's time structures
- theErr = CallMeWhen ( theNewCallBack,
- gAlterRateUpp,
- (long)hTempCallBackInfo,
- (**hTempCallBackInfo).param1,
- (**hTempCallBackInfo).param2,
- (**hTempCallBackInfo).param3 );
- if (theErr)
- ReportError( "\pError !! CallMeWhen", theErr );
- else
- {
-
- // --- Second call back - slow playback rate to 1/2 normal ----
-
- // Work out length of delay before callbacks start
- if (delayBeforeChange == kOneThird)
- theCallBackOffset = theMovieLen*0.6666;
- else
- theCallBackOffset = (2 * delayBeforeChange) * (**hDocMovieInfo).moviesTimeScale;
-
- // Create a new call back
- theNewCallBack = NewCallBack((**hDocMovieInfo).moviesTimeBase,callBackAtTime);
-
- newMovieRate = 32768; // speed up rate to 1/2 normal
-
- // Put the call back into call back chain ( and append newMovieRate )
- hTempCallBackInfo = AddNewCallBackInfo( pWindow,
- theNewCallBack,
- (Ptr)&newMovieRate, sizeof ( long ),
- triggerTimeFwd,
- theCallBackOffset,
- (**hDocMovieInfo).moviesTimeScale );
-
- // Attach the call back to the movie's time structures
- theErr = CallMeWhen ( theNewCallBack,
- gAlterRateUpp,
- (long)hTempCallBackInfo,
- (**hTempCallBackInfo).param1,
- (**hTempCallBackInfo).param2,
- (**hTempCallBackInfo).param3 );
- if (theErr)
- ReportError( "\pError !! CallMeWhen", theErr );
- }
- }
- return ( theErr );
- }
-
- //----------------------------------------------
- // SetupLoop
- //
- // Set up a loop in the movie.
- // - It uses call backs, to change the position of
- // the movie "loopWhen" seconds into it and moves it
- // to "loopTo" seconds
- //----------------------------------------------
-
- OSErr SetupLoop ( WindowPtr pWindow,
- short loopWhen,
- short loopTo )
- {
- OSErr theErr = noErr;
- DocMovieInfoHndl hDocMovieInfo; // Info about the windows movie
- long callBackWhen; // When we want to start loop
- CallBackInfoHdl hTempCallBackInfo; // Call back information
- QTCallBack tempCallBack; // Call Back
- TimeValue newTimeValue; // Where we want to loop to
-
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon (pWindow);
-
- // Calculate when the movie should 'jump'
- callBackWhen = loopWhen*(**hDocMovieInfo).moviesTimeScale;
-
- // Creates a call back
- tempCallBack = NewCallBack((**hDocMovieInfo).moviesTimeBase, callBackAtTime);
-
- // Set up where it's going to loop to
- newTimeValue = loopTo * (**hDocMovieInfo).moviesTimeScale;
-
- // Add the call back to the call back list
- hTempCallBackInfo = AddNewCallBackInfo( pWindow,
- tempCallBack,
- (Ptr) &newTimeValue, sizeof ( TimeValue ),
- triggerTimeFwd,
- callBackWhen,
- (**hDocMovieInfo).moviesTimeScale );
-
- // Attach the call back to the movie's time structures
- theErr = CallMeWhen( tempCallBack,
- gAlterMasterOffsetUpp, (long)hTempCallBackInfo,
- (**hTempCallBackInfo).param1,
- (**hTempCallBackInfo).param2,
- (**hTempCallBackInfo).param3 );
-
- return ( theErr );
- }
-
- //----------------------------------------------
- // SetupSlaveMovie
- //
- // This sets up the slaved movie
- // - "slaveAheadBy" sets the duration that the
- // slave will lead the master (in seconds)
- // - "slaveDelayStart" sets the duration that the
- // slave start will be delayed after the master starts
- // - If both values are set the same, the slave will start
- // n seconds behind the master and run in sync
- //----------------------------------------------
-
-
- OSErr SetupSlaveMovie ( WindowPtr pMasterWindow,
- WindowPtr pSlaveWindow,
- short slaveAheadBy,
- short slaveDelayStart )
- {
- OSErr theErr = noErr;
- DocMovieInfoHndl hDocMasterInfo; // masters info
- DocMovieInfoHndl hDocSlaveInfo; // slaves info
- long slaveTimeOffset; // difference between the two movies
- long slaveStartDelay; // when we've got to start the slave
- CallBackInfoHdl hTempCallBackInfo; // Call back information
- QTCallBack tempCallBack; // call back
- Movie movieToStart; // Put into the call back
- TimeValue theMovieLen; // Length of the movie
-
- // Get the info about the two movies
- hDocMasterInfo = (DocMovieInfoHndl)GetWRefCon (pMasterWindow);
- hDocSlaveInfo = (DocMovieInfoHndl)GetWRefCon (pSlaveWindow);
-
- // Attach the slave window onto the master
- (**hDocMasterInfo).pSlaveWind = pSlaveWindow;
-
- // Set the master movies time base value
- SetTimeBaseValue((**hDocMasterInfo).moviesTimeBase,0,(**hDocMasterInfo).moviesTimeScale);
-
- // slave second movie to first
- SetMovieMasterTimeBase( (**hDocSlaveInfo).actualMovie,
- (**hDocMasterInfo).moviesTimeBase,
- nil );
-
- // --- Setup the slave so it will lead the master ---
- if (slaveAheadBy != kInSync)
- {
- // Calculate how big the offset should be
- if (slaveAheadBy == kOneThird)
- {
- // get the movie's length
- theMovieLen = GetMovieDuration((**hDocSlaveInfo).actualMovie);
- slaveTimeOffset = theMovieLen*0.3333;
- }
- else
- slaveTimeOffset = slaveAheadBy*(**hDocMasterInfo).moviesTimeScale;
-
- // Set the slaves time base offset
- SetTimeBaseValue( (**hDocSlaveInfo).moviesTimeBase,
- slaveTimeOffset,
- (**hDocSlaveInfo).moviesTimeScale);
- theErr = GetAndReportError( "\pError !! - Offsetting timebase" );
- }
-
- // --- Put in the call back to start the slave movie (delayed if requested )--
-
- // Set up slaveStartDelay
- if (slaveDelayStart == kInSync)
- slaveStartDelay = 0;
- else
- if (slaveDelayStart == kOneThird)
- {
- // get the movie's length
- theMovieLen = GetMovieDuration((**hDocMasterInfo).actualMovie);
- slaveStartDelay = theMovieLen*0.3333;
- }
- else
- slaveStartDelay = slaveDelayStart * (**hDocMasterInfo).moviesTimeScale;
-
- // Create a new call back
- tempCallBack = NewCallBack((**hDocMasterInfo).moviesTimeBase,callBackAtTime);
-
- // Link the call back into the chain
- movieToStart = (**hDocSlaveInfo).actualMovie;
- hTempCallBackInfo = AddNewCallBackInfo( pMasterWindow,
- tempCallBack,
- (Ptr) &movieToStart, sizeof(Movie),
- triggerTimeFwd,
- slaveStartDelay,
- (**hDocMasterInfo).moviesTimeScale );
-
- // Attach the call back to the movie's time structures
- theErr = CallMeWhen ( tempCallBack, gStartMovieCBUpp,
- (long)hTempCallBackInfo,
- (**hTempCallBackInfo).param1,
- (**hTempCallBackInfo).param2,
- (**hTempCallBackInfo).param3 );
-
- ReportError( "\pError!! - Creating movie start call back", theErr );
-
- return ( theErr );
- }
-
-
- //----------------------------------------------
- // StartMovieWindow
- //
- // Start a movie in pWindow
- //----------------------------------------------
- OSErr StartMovieWindow( WindowPtr pWindow,
- Boolean fromBegining )
- {
- DocMovieInfoHndl hDocMovieInfo;
-
- if (pWindow)
- {
- hDocMovieInfo = (DocMovieInfoHndl)GetWRefCon (pWindow);
-
- // Set up the movie and start it
- if (fromBegining)
- GoToBeginningOfMovie((**hDocMovieInfo).actualMovie);
-
- SetMovieActive((**hDocMovieInfo).actualMovie,true);
- StartMovie((**hDocMovieInfo).actualMovie);
- }
- return( noErr );
- }
-
-